using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static System.Collections.Specialized.BitVector32;


[System.Serializable]
public class ItemGenerator {

	public ItemGenerator(IniFile fileItemTable,string section) {
		nothingWeight=(float)fileItemTable.GetDouble(section,"weightNothing");
		normalUpgradeWeight=(float)fileItemTable.GetDouble(section,"weightNormalUpgrade");
		healthPickupWeight=(float)fileItemTable.GetDouble(section,"weightHealthPickup");
		healthUpgradeWeight=(float)fileItemTable.GetDouble(section,"weightHealthUpgrade");
		upgradePointPickupWeight=(float)fileItemTable.GetDouble(section,"weightUpgradePointPickup");
		perkPickupWeight=(float)fileItemTable.GetDouble(section,"weightPerkPickup");
		weaponWeight=(float)fileItemTable.GetDouble(section,"weightWeapon");
		lootGrade=(float)fileItemTable.GetDouble(section,"lootGrade",1);
		uniqueUpgradeId=fileItemTable.GetInteger(section,"uniqueUpgradeId");
		priceMin=(float)fileItemTable.GetDouble(section,"priceMin");
		priceMax=(float)fileItemTable.GetDouble(section,"priceMax");
		LoadArray();
	}

	static GenerateMethod[] generateMethods;
	static ItemGenerator() {
		generateMethods=new GenerateMethod[methodTotal];
		generateMethods[0]=GenerateNull;
		generateMethods[1]=GenerateNormalUpgrade;
		generateMethods[2]=GenerateHealthPickup;
		generateMethods[3]=GenerateHealthUpgrade;
		generateMethods[4]=GenerateUpgradePointPickup;
		generateMethods[5]=GeneratePerkPickup;
		generateMethods[6]=GenerateWeapon;
	}

	const int nothing = 0;
	const int normalUpgrade = 1;
	const int healthPickup = 2;
	const int healthUpgrade = 3;
	const int upgradePointPickup = 4;
	const int perkPickup = 5;
	const int weapon = 5;
	const int methodTotal = 7;

	float nothingWeight;
	float normalUpgradeWeight;
	float healthPickupWeight;
	float healthUpgradeWeight;
	float upgradePointPickupWeight;
	float perkPickupWeight;
	float weaponWeight;
	float priceMin;
	float priceMax;

	float lootGrade;
	int uniqueUpgradeId;
	float[] generateMethodWeights;

	void LoadArray() {
		generateMethodWeights=new float[methodTotal];

		generateMethodWeights[0]=nothingWeight;
		generateMethodWeights[1]=normalUpgradeWeight;
		generateMethodWeights[2]=healthPickupWeight;
		generateMethodWeights[3]=healthUpgradeWeight;
		generateMethodWeights[4]=upgradePointPickupWeight;
		generateMethodWeights[5]=perkPickupWeight;
		generateMethodWeights[6]=weaponWeight;

	}

	public ItemPickup Generate(Vector2 position) {

		float generateMethodWeightSum = 0;
		foreach(float weight in generateMethodWeights) generateMethodWeightSum+=weight;

		int chosenMethod = 0;
		float chosenIndex = Random.Range(0,generateMethodWeightSum);
		for(int i = 0;i<methodTotal;i++) {
			if(chosenIndex<generateMethodWeights[i]) {
				chosenMethod=i;
				break;
			}
			chosenIndex-=generateMethodWeights[i];
		}
		ItemPickup result = generateMethods[chosenMethod](position,this);
		float price = Random.Range(priceMin,priceMax);
		if(result) result.price=Mathf.RoundToInt(price);
		return result;
	}

	static ItemPickup GenerateNull(Vector2 position,ItemGenerator sender) { return null; }
	static ItemPickup GenerateNormalUpgrade(Vector2 position,ItemGenerator sender) {
		float weightCommon = 1;
		float weightUncommon = weightCommon*sender.lootGrade;
		float weightRare = weightUncommon*sender.lootGrade;
		float weightSum = weightCommon+weightUncommon+weightRare;

		float generatedGrade = Random.Range(0,weightSum);
		int generatedRarity;
		if(generatedGrade<weightCommon) {
			generatedRarity=0;
		} else if(generatedGrade<weightUncommon+weightCommon) {
			generatedRarity=1;
		} else {
			generatedRarity=2;
		}

		int generatedId = Random.Range(0,UpgradeManager.upgradeCountByRarity[generatedRarity]);
		UpgradeData generatedData = UpgradeManager.upgradeByRarity[generatedRarity][generatedId];
		return UpgradePickup.Create(position,generatedData);
	}
	static ItemPickup GenerateHealthPickup(Vector2 position,ItemGenerator sender) { return HealthPickup.Create(position); }
	static ItemPickup GenerateHealthUpgrade(Vector2 position,ItemGenerator sender) { return HealthUpgrade.Create(position); }
	static ItemPickup GenerateUpgradePointPickup(Vector2 position,ItemGenerator sender) {

		int generatedLevel = Game.currentLevel.lootLevel;

		if(sender.lootGrade<=0) generatedLevel--;
		if(sender.lootGrade<=-1) generatedLevel--;
		if(sender.lootGrade>=2) generatedLevel++;
		if(sender.lootGrade>=3) generatedLevel++;

		if(sender.lootGrade<=1&&Utility.Chance(0.2f)) generatedLevel--;
		if(sender.lootGrade>=1&&Utility.Chance(0.05f)) generatedLevel--;
		if(sender.lootGrade<=1&&Utility.Chance(0.01f)) generatedLevel++;
		if(sender.lootGrade>=1&&Utility.Chance(0.1f)) generatedLevel++;

		if(generatedLevel==0) return null;
		return UpgradePointPickup.Create(position,generatedLevel);
	}
	static ItemPickup GeneratePerkPickup(Vector2 position,ItemGenerator sender) {
		int generateId = Random.Range(1,Perk.perkCount);
		while(Perk.IfPerkEquipped(generateId)) generateId=Random.Range(1,Perk.perkCount);
		return PerkPickup.Create(position,generateId);
	}
	static ItemPickup GenerateWeapon(Vector2 position,ItemGenerator sender) {
		WeaponData toCreate = null;
		do {
			int index = WeaponData.weaponDatas.Count;
			index=Random.Range(0,index);
			toCreate=WeaponData.weaponDatas[index];
			if(toCreate.tags.HasFlag(WeaponTags.EnemyWeapon)) toCreate=null;
		} while(toCreate==null);

		int generatedLevel = Game.currentLevel.lootLevel;
		if(sender.lootGrade<=0) generatedLevel--;
		if(sender.lootGrade<=-1) generatedLevel--;
		if(sender.lootGrade>=2) generatedLevel++;
		if(sender.lootGrade>=3) generatedLevel++;


		WeaponPickup result = WeaponPickup.Create(position,toCreate);
		result.weapon.weaponLevel+=generatedLevel;
		return result;
	}

	delegate ItemPickup GenerateMethod(Vector2 position,ItemGenerator sender);
}
